package com.ch3cooh.proxy;

import com.ch3cooh.registry.util.StringUtils;
import com.ch3cooh.rpc.annotation.HttpRpc;
import com.ch3cooh.rpc.util.ScannerUtils;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.config.BeanDefinition;
import org.springframework.beans.factory.config.ConfigurableListableBeanFactory;
import org.springframework.beans.factory.support.BeanDefinitionBuilder;
import org.springframework.beans.factory.support.BeanDefinitionRegistry;
import org.springframework.beans.factory.support.BeanDefinitionRegistryPostProcessor;
import org.springframework.beans.factory.support.GenericBeanDefinition;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import java.util.List;

/**
 * @功能: 扫描出所有带有@Rpc注解的接口，并自动生成实现类向spring动态注册代理对象bean
 * @作者:chanson
 * @时间:2018/4/29 16:53
 */
@Component
public class ProxyRegistry implements BeanDefinitionRegistryPostProcessor{

 //  public final static Map<String,Class> proxyMap = new HashMap<>();

    @Autowired
    Environment env;

    @Override
    public void postProcessBeanDefinitionRegistry(BeanDefinitionRegistry beanDefinitionRegistry) throws BeansException {
        //找出所有标注@Rpc注解的接口，并生成接口的代理实现类
        List<Class> extraBeanClasses = ScannerUtils.scanInterfaceByAnnotation("", HttpRpc.class);
        for(Class clazz : extraBeanClasses){
                String beanName = getRawBeanName(clazz);
                //如果之前存在有 beanName ,那么就跳过生成接口代理类,因为这是真正的实现类
                 if ( beanDefinitionRegistry.containsBeanDefinition(beanName + "Impl") ){
                    continue;
                 }

          //      System.out.println("准备注册bean: " + beanName+"("+clazz.getName()+")" );
                BeanDefinitionBuilder builder = BeanDefinitionBuilder.genericBeanDefinition(clazz);
                GenericBeanDefinition beanDefinition = (GenericBeanDefinition) builder.getRawBeanDefinition();

                beanDefinition.setBeanClass(ProxyFactory.class);
          //      System.out.println("beanDefinitionClassName: " + beanDefinition.getBeanClassName());
                beanDefinition.getPropertyValues().add("interfaceClass", clazz.getName());
                beanDefinition.setLazyInit(false);
                beanDefinition.setAutowireCandidate(true);
                beanDefinition.setAutowireMode(GenericBeanDefinition.AUTOWIRE_BY_TYPE);
                beanDefinitionRegistry.registerBeanDefinition(beanName,beanDefinition);
           //     System.out.println("注册bean: " + clazz.getName() );
            BeanDefinition userService = beanDefinitionRegistry.getBeanDefinition("userService");
         //   System.out.println("ok");
        }
    }

    @Override
    public void postProcessBeanFactory(ConfigurableListableBeanFactory configurableListableBeanFactory) throws BeansException {

    }

    /**
     * 获取一个bean缺省的id名
     * @param clazz     比如"com.abc.UserService"
     * @return  返回id名为"userService"
     */
    private String getRawBeanName(Class clazz) {
        String className = clazz.getName();
        String beanName = className.substring(className.lastIndexOf(".") + 1);
        beanName = StringUtils.firstCharUpper(beanName);
        return beanName;

    }

    public static void main(String[] args) {
        List<Class> extraBeanClasses = ScannerUtils.scanInterfaceByAnnotation("", HttpRpc.class);
        extraBeanClasses.forEach(System.out::println);
    }

}
